package qiniu.voidcepc.voicepc.demos.web.vo.musicvo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import qiniu.voidcepc.voicepc.demos.web.exception.BusinessException;
import qiniu.voidcepc.voicepc.demos.web.utils.MouseCoordinateHelper;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.Objects;

/**
 * 酷我音乐播放器控制服务类
 * 提供对酷我音乐播放器的启动、搜索和播放等操作
 */
@Service
public class KuWoMusicPlayer {
    // 常量定义
    private static final int DELAY_SHORT = 100;     // 短延迟(毫秒)
    private static final int DELAY_MEDIUM = 1000;   // 中等延迟(毫秒)
    private static final int DELAY_LONG = 3000;     // 长延迟(毫秒)
    private static final int DELAY_STARTUP = 5000;  // 应用启动延迟(毫秒)
    
    // 搜索框和搜索结果位置坐标
    @Value("${mouse.search.x}")
    private  int SEARCH_BOX_X;
    @Value("${mouse.search.y}")
    private  int SEARCH_BOX_Y;
    @Value("${mouse.play.x}")
    private  int FIRST_RESULT_X;
    @Value("${mouse.play.y}")
    private  int FIRST_RESULT_Y;

    
    @Value("${apppath.music}")
    private String appPath; // 应用程序路径

    @Autowired
    private Robot robot; // 用于模拟鼠标和键盘操作

    /**
     * 初始化方法，启动酷我音乐播放器
     * 使用@PostConstruct确保在依赖注入完成后执行
     */
    @javax.annotation.PostConstruct
    public void init() {
        if (appPath != null && !appPath.isEmpty()) {
            try {
                startApp();
                // 打印屏幕尺寸信息用于调试
                Dimension screenSize = getScreenSize();
                System.out.printf("屏幕尺寸: 宽度=%d, 高度=%d%n", screenSize.width, screenSize.height);
                
                // 等待应用完全启动
                safeSleep(DELAY_STARTUP);
            } catch (Exception e) {
                System.err.printf("启动酷我音乐播放器失败: %s%n", e.getMessage());
                // 记录异常但不抛出，允许应用继续运行
            }
        } else {
            System.err.println("酷我音乐播放器路径未配置，跳过启动步骤");
        }
    }

    /**
     * 启动酷我音乐应用程序
     * @throws IOException 当启动应用失败时抛出
     * @throws IllegalStateException 当应用路径未配置时抛出
     */
    private void startApp() throws IOException {
        if (appPath == null || appPath.isEmpty()) {
            throw new IllegalStateException("酷我音乐播放器路径未配置(appPath.music)");
        }
        // 使用ProcessBuilder处理可能包含空格的Windows路径
        ProcessBuilder processBuilder = new ProcessBuilder(appPath);
        processBuilder.start();
    }

    /**
     * 获取屏幕尺寸
     * @return 屏幕尺寸对象
     */
    public Dimension getScreenSize() {
        return Toolkit.getDefaultToolkit().getScreenSize();
    }

    /**
     * 搜索并播放指定的音乐
     * @param songName 歌曲名称
     * @param artistName 艺术家名称（可选）
     * @return 操作结果消息
     * @throws BusinessException 当操作过程中发生业务异常时抛出
     */
    public String searchAndPlay(String songName, String artistName) {
        Objects.requireNonNull(songName, "歌曲名称不能为空");
        
        // 首先检查应用路径是否已配置
        if (appPath == null || appPath.isEmpty()) {
            throw new BusinessException("酷我音乐播放器路径未配置，请在配置文件中设置appPath.music", "400");
        }
        
        try {
            // 启动应用
            startApp();
            
            // 检查Robot实例是否可用
            if (robot == null) {
                throw new BusinessException("Robot实例不可用，可能在无头环境中运行", "500");
            }
            
            // 构建搜索目标文本
            String target = buildSearchTarget(songName, artistName);
            
            // 执行搜索和播放操作
            performSearchAndPlay(target);
            
            return "播放成功";
        } catch (IOException e) {
            System.err.printf("启动酷我音乐播放器失败: %s%n", e.getMessage());
            throw new BusinessException("启动播放器失败", "500", e);
        } catch (Exception e) {
            System.err.printf("执行音乐搜索和播放时发生错误: %s%n", e.getMessage());
            throw new BusinessException("执行音乐搜索和播放时发生错误", "500", e);
        }
    }

    /**
     * 执行歌曲的暂停或者播放
     * @return 操作结果消息
     * @throws IOException 当启动应用失败时抛出
     */
    public String stopOrdisplaySing() throws IOException {
        // 启动应用
        startApp();
        
        // 检查Robot实例是否可用
        if (robot == null) {
            return "Robot实例不可用，无法执行暂停/播放操作";
        }

        safeSleep(DELAY_MEDIUM);
        // 快捷键F5控制播放/暂停
        robot.keyPress(KeyEvent.VK_F5);
        robot.keyRelease(KeyEvent.VK_F5);
        
        return "播放/暂停操作执行成功";
    }
    
    /**
     * 构建搜索目标文本
     * @param songName 歌曲名称
     * @param artistName 艺术家名称（可选）
     * @return 构建好的搜索目标文本
     */
    private String buildSearchTarget(String songName, String artistName) {
        if (artistName != null && !artistName.trim().isEmpty()) {
            return songName.trim() + " " + artistName.trim();
        } else {
            return songName.trim();
        }
    }
    
    /**
     * 执行搜索和播放操作
     * @param searchTarget 搜索目标文本
     * @throws InterruptedException 当线程被中断时抛出
     */
    private void performSearchAndPlay(String searchTarget) throws InterruptedException {
        // 移动到搜索框位置并点击
        Point searchBoxPoint = MouseCoordinateHelper.physicalToLogical(SEARCH_BOX_X, SEARCH_BOX_Y);
        robot.mouseMove(searchBoxPoint.x, searchBoxPoint.y);
        safeSleep(DELAY_MEDIUM);
        
        // 清除搜索框中现有内容
        clickMouse();
        safeSleep(DELAY_SHORT);
        selectAll();
        pressDelete();
        safeSleep(DELAY_LONG);
        
        // 再次点击并输入搜索内容
        clickMouse();
        safeSleep(DELAY_LONG);
        typeString(searchTarget);
        
        // 按下回车键执行搜索
        safeSleep(DELAY_STARTUP);//增加等待时间
        pressEnter();
        
        // 等待搜索结果加载
        safeSleep(DELAY_LONG);
        
        // 点击第一个搜索结果
        Point resultPoint = MouseCoordinateHelper.physicalToLogical(FIRST_RESULT_X, FIRST_RESULT_Y);
        robot.mouseMove(resultPoint.x, resultPoint.y);
        clickMouse();
    }

    /**
     * 模拟键盘输入文本
     * @param text 要输入的文本
     */
    private void typeString(String text) {
        if (robot == null || text == null || text.isEmpty()) {
            return;
        }
        
        for (char c : text.toCharArray()) {
            int keyCode = KeyEvent.getExtendedKeyCodeForChar(c);
            
            // 检查键码是否有效，避免Invalid key code异常
            boolean isValidKeyCode = isValidKeyCode(keyCode);
            
            if (isValidKeyCode) {
                // 处理大写字母需要按下Shift键
                boolean needShift = Character.isUpperCase(c);
                if (needShift) {
                    robot.keyPress(KeyEvent.VK_SHIFT);
                }

                // 按下并释放键
                robot.keyPress(keyCode);
                robot.keyRelease(keyCode);

                // 释放Shift键
                if (needShift) {
                    robot.keyRelease(KeyEvent.VK_SHIFT);
                }

                // 模拟人类输入速度
                safeSleep(DELAY_SHORT);
            } else {
                System.out.printf("跳过无法映射的字符: %c (键码: %d)%n", c, keyCode);
            }
        }
    }
    
    /**
     * 检查键码是否有效
     * @param keyCode 要检查的键码
     * @return 如果键码有效则返回true
     */
    private boolean isValidKeyCode(int keyCode) {
        return (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_Z) ||
               (keyCode >= KeyEvent.VK_NUMPAD0 && keyCode <= KeyEvent.VK_NUMPAD9) ||
               (keyCode == KeyEvent.VK_SPACE) ||
               (keyCode == KeyEvent.VK_COMMA) ||
               (keyCode == KeyEvent.VK_PERIOD) ||
               (keyCode == KeyEvent.VK_SLASH) ||
               (keyCode == KeyEvent.VK_BACK_SLASH) ||
               (keyCode == KeyEvent.VK_SEMICOLON) ||
               (keyCode == KeyEvent.VK_EQUALS) ||
               (keyCode == KeyEvent.VK_MINUS);
    }

    /**
     * 模拟Ctrl+A（全选）操作
     */
    private void selectAll() {
        if (robot == null) {
            return;
        }
        
        robot.keyPress(KeyEvent.VK_CONTROL);
        robot.keyPress(KeyEvent.VK_A);
        robot.delay(DELAY_SHORT);
        robot.keyRelease(KeyEvent.VK_A);
        robot.keyRelease(KeyEvent.VK_CONTROL);
    }
    
    /**
     * 模拟Delete键操作
     */
    private void pressDelete() {
        if (robot == null) {
            return;
        }
        
        robot.keyPress(KeyEvent.VK_DELETE);
        robot.keyRelease(KeyEvent.VK_DELETE);
    }
    
    /**
     * 模拟Enter键操作
     */
    private void pressEnter() {
        if (robot == null) {
            return;
        }
        
        robot.keyPress(KeyEvent.VK_ENTER);
        robot.keyRelease(KeyEvent.VK_ENTER);
    }
    
    /**
     * 模拟鼠标点击操作
     */
    private void clickMouse() {
        if (robot == null) {
            return;
        }
        
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }
    
    /**
     * 安全地执行线程睡眠，处理InterruptedException异常
     * @param millis 睡眠时长（毫秒）
     */
    private void safeSleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 重置中断状态
            System.err.printf("线程睡眠被中断: %s%n", e.getMessage());
        }
    }

}
